from starlette.endpoints import HTTPEndpoint
from starlette.responses import JSONResponse
from model.ModDepartmentVsBureau import DepartmentVsBureau,depvsbureauSchema
from database import Session, engine
import config
from dao import DaoDepartmentVsBureau
import uuid
import requests
from redis_connection import redis_conn as redis


def calculate_department_level(departments, department_id) -> int:
    level = 0
    scans = [department_id]
    while len(scans) > 0:
        search_target = scans.pop()
        level += 1
        currents = filter(lambda p: p["id"] == search_target, departments)
        try:
            current = next(currents)
            if current["parentid"] == 0:
                break
            scans.append(current["parentid"])
        except StopIteration:
            break
    return level


class DepartmentVsBureauControl(HTTPEndpoint):
    async def get(self, request):
        session = Session()
        try:
           return DaoDepartmentVsBureau.get_department_list(session)
        finally:
            session.close()

    async def post(self, request):
        session = Session()
        try:
            token = redis.hget(config.ENT_ACCESS_TOKEN, "token")
            dep_respone = requests.get("https://qyapi.weixin.qq.com/cgi-bin/department/list",
                                       params={
                                           "access_token": token
                                       })
            dep_respone.raise_for_status()
            dep_data = dep_respone.json()
            if "errcode" in dep_data and dep_data["errcode"] == 0:
                departments = dep_data["department"]
                maintained_departments = session.query(DepartmentVsBureau).all()
                for department in departments:
                    department["level"] = calculate_department_level(departments, department["id"])
                    # 判断是否已经存在
                    if any([md.departmentid == department["id"] for md in maintained_departments]):
                        exist_department = next(filter(lambda md: md.departmentid == department["id"],
                                                       maintained_departments))
                        if exist_department.department_name != department["name"]:
                            exist_department.department_name = department["name"]
                        if exist_department.higher_department != department["parentid"]:
                            exist_department.higher_department = department["parentid"]
                        if exist_department.level != department["level"]:
                            exist_department.level = department["level"]
                        if exist_department.bureauid is None:
                            exist_department.bureauid = "00"
                    else:
                        new_department = DepartmentVsBureau()
                        new_department.departmentid = department["id"]
                        new_department.department_name = department["name"]
                        new_department.bureauid = "00"
                        new_department.higher_department = department["parentid"]
                        new_department.level = department["level"]
                        session.add(new_department)
            else:
                raise ValueError()
            session.commit()
            return JSONResponse({"result": "1"})
        except (requests.HTTPError, ValueError):
            session.rollback()
            return JSONResponse({"result": "0"})
        finally:
            session.close()

    async def put(self, request):
        session = Session()
        try:
            dict_department = await request.json()
            departmentid = dict_department.get("departmentid")
            bureauid = dict_department.get("bureauid")
            DaoDepartmentVsBureau.update_department_info(session, departmentid, bureauid)
            session.commit()
        except Exception as e:
            session.rollback()
            return JSONResponse({"result": "0"})
        else:
            return JSONResponse({"result": "1"})
        finally:
            session.close()

